package org.jeecg.modules.product.risk.thread;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.collections.CollectionUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.product.risk.entity.*;
import org.jeecg.modules.product.risk.service.*;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class SyncBaseCheckJob implements Job {
    private static int delayInMinutes = 2; // 休息2分钟
    private static long delayInMillis = delayInMinutes * 60 * 1000; // 转换为毫秒

    @Value("${doubleControl.getCheckTaskUrl}")
    private String checkTaskUrl;

    @Value("${doubleControl.getCheckItemUrl}")
    private String checkItemUrl;

    @Value("${doubleControl.getCheckScoreUrl}")
    private String checkScoreUrl;

    @Value("${doubleControl.token}")
    private String token;

    @Autowired
    private ITbBaseCheckTaskService baseCheckTaskService;

    @Autowired
    private ITbBaseCheckItemService baseCheckItemService;

    @Autowired
    private ITbBaseCheckScoreService baseCheckScoreService;

    @Autowired
    private ITbBaseCheckService baseCheckService;
    @Autowired
    private ITbBaseCheckCompanyService tbBaseCheckCompanyService;

    public static final MediaType MEDIA_TYPE_MARKDOWN
            = MediaType.parse("text/x-markdown; charset=utf-8");
    public static final MediaType MEDIA_TYPE_JSON
            = MediaType.parse("application/json; charset=utf-8");

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        QueryWrapper<TbBaseCheckCompany> queryWrapper = new QueryWrapper<>();
        List<TbBaseCheckCompany> checkCompanyList = tbBaseCheckCompanyService.list(queryWrapper);
        if(!CollectionUtils.isEmpty(checkCompanyList)) {
            for (TbBaseCheckCompany checkCompany : checkCompanyList) {
                //获取检查表任务
                String authorization = token+DateUtils.formatDate(new Date(),"yyyyMMddHHmmssSSS");
                doSyncCheckTask(authorization,checkCompany.getCompanyCode(),checkCompany.getSysOrgCode());
                try {
                    Thread.sleep(delayInMillis);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    private void doSyncCheckTask(String authorization,String companyCode,String sysOrgCode) {
        OkHttpClient client = new OkHttpClient();
        JSONObject jsonBody = new JSONObject();
        jsonBody.put("companyCodes", new String[]{companyCode});
        try {
            Request request = new Request.Builder()
                    .url(checkTaskUrl)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "application/json")
                    .addHeader("Authorization", authorization)
                    .addHeader("Cache-Control", "no-cache")
                    .post(RequestBody.create(MEDIA_TYPE_JSON, jsonBody.toJSONString()))
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String resultStr = response.body().string();
                log.debug(resultStr);
                JSONObject resultJson = JSONObject.parseObject(resultStr);
                if ("200".equals(resultJson.getString("code"))) {
                    log.debug(resultJson.getString("msg"));
                    List<TbBaseCheckTask> baskCheckTaskList = JSONArray.parseArray(resultJson.getString("obj"), TbBaseCheckTask.class);
                    baskCheckTaskList.forEach(item -> {
                        item.setSysOrgCode(sysOrgCode);
                        item.setSysOrgCode(companyCode);
                        TbBaseCheckTask baseCheckTask = baseCheckTaskService.getOne(new LambdaQueryWrapper<TbBaseCheckTask>().eq(TbBaseCheckTask::getId, item.getId()));
                        TbBaseCheck baseCheck = baseCheckService.getOne(new LambdaQueryWrapper<TbBaseCheck>().eq(TbBaseCheck::getId, item.getId()));
                        if (baseCheckTask!=null && item.getId().equals(baseCheckTask.getId())){
                            baseCheckTaskService.updateById(item);
                        }else{
                            baseCheckTaskService.saveOrUpdate(item);
                            baseCheck = new TbBaseCheck();
                            baseCheck.setSysOrgCode(sysOrgCode);
                            baseCheck.setName(item.getTaskName());
                            baseCheck.setId(item.getId());   //任务标识作为检查表标识
                            baseCheck.setDeleted(CommonConstant.DEL_FLAG_0.toString());
                            baseCheck.setAim(item.getTaskContent());
                            baseCheck.setInspectionStandardType(item.getTaskTypeName()); //todo 检查类型如何定义
                            baseCheckService.save(baseCheck);
                        }
                        log.info("-------获取到的任务专项检查任务条数-----------------"+baskCheckTaskList.size());
                        doSyncCheckItem(authorization, sysOrgCode, item.getId(),baseCheck.getId(),1,1000);  //同步检查项信息
                    });
                }else{
                    log.warn(resultJson.getString("msg"));
                }
            } else {
                throw new RuntimeException("查询专项检查任务信息失败,错误码为: " + response.code());
            }
            Thread.sleep(delayInMillis);
        } catch (IOException e) {
            log.error("------------------获取专项检查任务数据异常-------------------"+e.getMessage(),e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询检查项信息
     * @param taskId  专项检查任务标识
     * @param current 分页当前页，始于1
     * @param size    页长，默认100
     */
    private void doSyncCheckItem(String authorization, String sysOrgCode, String taskId, String checkId, int current, int size) {
        OkHttpClient client = new OkHttpClient();
        JSONObject jsonBody = new JSONObject();
        jsonBody.put("taskId",taskId);
        JSONObject pageJson = new JSONObject();
        pageJson.put("size", size);
        pageJson.put("current", current);
        jsonBody.put("page", pageJson);
        try {
            Request request = new Request.Builder()
                    .url(checkItemUrl)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "application/json")
                    .addHeader("Authorization", authorization)
                    .addHeader("Cache-Control", "no-cache")
                    .post(RequestBody.create(MEDIA_TYPE_JSON, jsonBody.toJSONString()))
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String resultStr = response.body().string();
                log.debug(resultStr);
                JSONObject resultJson = JSONObject.parseObject(resultStr);
                if ("200".equals(resultJson.getString("code"))) {
                    log.debug(resultJson.getString("msg"));
                    List<TbBaseCheckItem> baskCheckList = JSONArray.parseArray(resultJson.getJSONObject("obj").getString("records"), TbBaseCheckItem.class);
                    baskCheckList.forEach(item -> {
                        item.setCheckId(checkId);
                        item.setSysOrgCode(sysOrgCode);
                        TbBaseCheckItem baseCheckItem = baseCheckItemService.getOne(new LambdaQueryWrapper<TbBaseCheckItem>().eq(TbBaseCheckItem::getId, item.getId()).eq(TbBaseCheckItem::getTaskId,item.getTaskId()));
                        if (baseCheckItem!=null && item.getId().equals(baseCheckItem.getId())){
                            baseCheckItemService.updateById(item);
                        }else{
                            item.setCheckId(checkId);
                            baseCheckItemService.saveOrUpdate(item);
                        }
                        doSyncCheckScore(authorization, sysOrgCode, item.getTaskId(), item.getId(), 1,1000);
                    });
                    log.info("-------获取到的检查项条数-----------------"+baskCheckList.size());
                    if (resultJson.getJSONObject("obj").getInteger("total") > size * current) {
                        doSyncCheckItem(authorization, sysOrgCode,taskId, checkId,current + 1, size);
                    }
                }else{
                    log.warn(resultJson.getString("msg"));
                }
            } else {
                log.error("------------------请求异常,错误码为:------------------"+response.code());
                throw new RuntimeException("请求异常,错误码为: " + response.code());
            }
        } catch (IOException e) {
            log.error("------------------获取专项检查任务数据异常-------------------"+e.getMessage(),e);
        }
    }

    /**
     * 获取检查项评份细则
     * @param taskId       专项检查任务标识
     * @param checkItemId  传项检查任务项标识
     * @param current      当前页
     * @param size         页幅
     */
    private void doSyncCheckScore(String authorization, String sysOrgCode, String taskId, String checkItemId, int current, int size) {
        OkHttpClient client = new OkHttpClient();
        JSONObject jsonBody = new JSONObject();
        jsonBody.put("taskId",taskId);
        jsonBody.put("checkItemId",checkItemId);
        JSONObject pageJson = new JSONObject();
        pageJson.put("size", size);
        pageJson.put("current", current);
        jsonBody.put("page", pageJson);
        try {
            Request request = new Request.Builder()
                    .url(checkScoreUrl)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "application/json")
                    .addHeader("Authorization", authorization)
                    .addHeader("Cache-Control", "no-cache")
                    .post(RequestBody.create(MEDIA_TYPE_JSON, jsonBody.toJSONString()))
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String resultStr = response.body().string();
                log.debug(resultStr);
                JSONObject resultJson = JSONObject.parseObject(resultStr);
                if ("200".equals(resultJson.getString("code"))) {
                    log.debug(resultJson.getString("msg"));
                    List<TbBaseCheckScore> checkScoreList = JSONArray.parseArray(resultJson.getJSONObject("obj").getString("records"), TbBaseCheckScore.class);
                    checkScoreList.forEach(item -> {
                        item.setSysOrgCode(sysOrgCode);
                        TbBaseCheckScore checkScore = baseCheckScoreService.getOne(new LambdaQueryWrapper<TbBaseCheckScore>().eq(TbBaseCheckScore::getId, item.getId()).eq(TbBaseCheckScore::getCheckItemId,item.getCheckItemId()));
                        if (checkScore!=null && item.getId().equals(checkScore.getId())){
                            baseCheckScoreService.updateById(item);
                        }else{
                            baseCheckScoreService.saveOrUpdate(item);
                        }
                    });
                    if (resultJson.getJSONObject("obj").getInteger("total") > size * current) {
                        doSyncCheckScore(authorization, sysOrgCode, taskId, checkItemId,current + 1, size);
                    }
                    log.info("-------获取到的任务专项检查细则条数-----------------"+checkScoreList.size());
                }else{
                    log.warn(resultJson.getString("msg"));
                }
            } else {
                log.error("------------------请求异常,错误码为:------------------"+response.code());
                throw new RuntimeException("请求异常,错误码为: " + response.code());
            }
        } catch (IOException e) {
            log.error("------------------获取专项检查项评份细则数据异常-------------------"+e.getMessage(),e);
        }
    }
}
